<template>
    <div class="app-container">
        <div class="header">
            <div class="operation">
                <el-button type="primary" @click="Add">新建</el-button>
                <el-button type="success" @click="Refresh">刷新</el-button>
                <el-button type="primary" @click="Edit">编辑</el-button>
                <el-button type="danger" @click="Delete">删除</el-button>
            </div>
        </div>

        <el-table
            v-loading="loading"
            :data="rolesList"
            ref="table"
            border
            @row-click="handleRowClick"
            @selection-change="handleSelectionChange"
        >
            <el-table-column type="selection" width="55" align="center">
            </el-table-column>
            <el-table-column align="center" label="序号" width="95">
                <template slot-scope="scope">
                    {{ scope.$index + 1 }}
                </template>
            </el-table-column>
            <el-table-column type="expand" label="模块权限" width="100">
                <template slot-scope="scope">
                    <span v-if="scope.row.menuList == null"> 未分配权限 </span>
                    <el-tag
                        v-else
                        v-for="(menu, index) of scope.row.menuList"
                        :key="index"
                        style="margin: 0 15px 5px 0"
                        >{{ menu.menuName }}</el-tag
                    >
                </template>
            </el-table-column>

            <el-table-column label="角色名称" width="220">
                <template slot-scope="scope">
                    {{ scope.row.roleName }}
                </template>
            </el-table-column>
            <el-table-column align="center" width="100" label="角色状态">
                <template slot-scope="scope">
                    <el-tag
                        :type="scope.row.status == '1' ? 'primary' : 'danger'"
                        >{{
                            scope.row.status | statusFilter(scope.row.status)
                        }}</el-tag
                    >
                </template>
            </el-table-column>
            <el-table-column label="角色编码" width="220" prop="roleCode">
            </el-table-column>
            <el-table-column label="角色描述" prop="description">
            </el-table-column>
        </el-table>

        <el-pagination
            :page-size="limit"
            class="pagination"
            background
            layout="prev, pager, next"
            :total="total"
            @current-change="handlePageChange"
        >
        </el-pagination>

        <el-dialog
            :visible.sync="dialogVisible"
            :close-on-click-modal="false"
            :title="dialogType === 'edit' ? '编辑角色' : '新建角色'"
        >
            <el-form
                :model="role"
                label-width="100px"
                style="padding: 0 15px 0 0"
            >
                <el-form-item label="角色名称:">
                    <el-input v-model="role.roleName" />
                </el-form-item>
                <el-form-item label="角色描述:">
                    <el-input
                        v-model="role.description"
                        :autosize="{ minRows: 2, maxRows: 4 }"
                        type="textarea"
                    />
                </el-form-item>
                <el-form-item label="角色编码:">
                    <el-input v-model="role.roleCode" />
                </el-form-item>
                <el-form-item label="角色状态:">
                    <el-switch
                        v-model="role.status"
                        :active-value="1"
                        :inactive-value="2"
                    ></el-switch>
                </el-form-item>
                <el-form-item label="菜单权限:">
                    <tree-select
                        :options="menuOptions"
                        :multiple="true"
                        placeholder="0为一级菜单"
                        v-model="role.menus"
                        :flat="true"
                        :autoSelectAncestors="true"
                        no-children-text="没有子节点"
                        :normalizer="normalizer"
                    >
                    </tree-select>
                </el-form-item>
            </el-form>
            <div style="text-align: right">
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="confirmRole">保存</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import { pageSize } from "@/settings";
import { deepClone } from "@/utils";
import { getTreeMenu } from "@/api/menu";
import { addRole, deleteRole, updateRole, selectPage } from "@/api/role";
const defaultRole = {
    roleName: "",
    description: "",
    roleCode: "",
    status: 1,
    menus: [],
};

export default {
    data() {
        return {
            role: Object.assign({}, defaultRole),
            routes: [],
            rolesList: [],
            dialogVisible: false,
            dialogType: "new",
            checkStrictly: false,
            defaultProps: {
                children: "children",
                label: "title",
            },
            loading: false,
            start: 0,
            limit: pageSize,
            total: 0,
            page: 1, // 当前页码
            selectData: [],
            menuOptions: [],
        };
    },
    computed: {
        menuData() {
            return this.routes;
        },
    },
    created() {
        this.getRoles();
        this.getMenus();
    },
    methods: {
        Add() {
            this.role = Object.assign({}, defaultRole);
            this.dialogType = "new";
            this.dialogVisible = true;
        },
        Refresh() {
            this.start = (this.page - 1) * this.limit;
            this.getRoles();
        },
        getMenus() {
            getTreeMenu().then((res) => {
                this.transferOption(res.data);
                this.menuOptions = res.data;
            });
        },
        // 删除option中的空children节点
        transferOption(menus) {
            menus.forEach((menu) => this.processMenuNode(menu));
        },
        // 处理节点
        processMenuNode(node) {
            if (node.children == null || node.children.length == 0) {
                return delete node.children;
            } else {
                node.children.forEach((child) => this.processMenuNode(child));
            }
        },
        Edit() {
            debugger;
            if (this.selectData.length == 0) {
                return this.$message.error("未选择任何数据");
            }
            if (this.selectData.length !== 1) {
                return this.$message.error("只能操作一条数据");
            }
            this.dialogType = "edit";
            this.role = Object.assign({}, this.selectData[0]);
            if (this.role.menus) {
                this.role.menus = this.role.menus.split(",");
            }
            this.dialogVisible = true;
        },
        normalizer(node) {
            return {
                id: node.id,
                label: node.menuName,
                children: node.children,
            };
        },
        Delete() {
            if (this.selectData.length == 0) {
                return this.$message.error("未选择任何数据");
            }
            if (this.selectData.length > 1) {
                return this.$message.error("只能选择一条数据");
            }
            this.$confirm("确定要删除这个角色吗?", "删除提醒", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(async () => {
                    await deleteRole({ id: this.selectData[0].id });
                    this.getRoles();
                    this.$message({
                        type: "success",
                        message: "删除成功",
                    });
                })
                .catch((err) => {
                    console.error(err);
                });
        },
        handlePageChange(param) {
            this.page = param;
            this.start = (param - 1) * this.limit;
            this.getRoles();
        },
        handleRowClick(row) {
            this.$refs.table.toggleRowSelection(row);
        },
        handleSelectionChange(selection) {
            this.selectData = selection;
        },
        async getRoles() {
            this.loading = true;
            const res = await selectPage({
                start: this.start,
                limit: this.limit,
            });
            this.loading = false;
            const { total, records } = res.data;
            this.rolesList = records;
            this.total = total;
        },

        handleEdit(scope) {
            this.dialogType = "edit";
            this.dialogVisible = true;
            this.checkStrictly = true;
            this.role = deepClone(scope.row);
        },
        generateTree(routes, basePath = "/", checkedKeys) {
            const res = [];

            for (const route of routes) {
                const routePath = path.resolve(basePath, route.path);

                // recursive child routes
                if (route.children) {
                    route.children = this.generateTree(
                        route.children,
                        routePath,
                        checkedKeys
                    );
                }

                if (
                    checkedKeys.includes(routePath) ||
                    (route.children && route.children.length >= 1)
                ) {
                    res.push(route);
                }
            }
            return res;
        },
        async confirmRole() {
            const isEdit = this.dialogType === "edit";
            let res;
            if (isEdit) {
                res = await updateRole(this.role.key, this.role);
            } else {
                res = await addRole(this.role);
            }
            if (res.code == 200) {
                this.$message.success(res.message);
            } else {
                this.$message.error("操作失败");
            }
            this.getRoles();
            this.dialogVisible = false;
        },
    },
};
</script>

<style lang="scss" scoped>
.app-container {
    .header {
        display: flex;
        justify-content: flex-end;
        margin-bottom: 20px;
    }
    .pagination {
        margin-top: 20px;
    }
    .permission-tree {
        margin-bottom: 30px;
    }
}
</style>
<style scoped>
.app-container >>> .el-form-item--medium .el-form-item__content {
    line-height: 20px;
}
</style>
